/**
 * ANNCSR (2010-2011)
 */
package net.abbp.mtr;

import java.awt.BorderLayout;
import java.awt.Dimension;
import java.awt.FlowLayout;
import java.awt.Window;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Vector;

import javax.swing.BorderFactory;
import javax.swing.JButton;
import javax.swing.JFileChooser;
import javax.swing.JLabel;
import javax.swing.JOptionPane;
import javax.swing.JPanel;
import javax.swing.JScrollPane;
import javax.swing.JTable;
import javax.swing.SwingUtilities;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.swing.table.DefaultTableModel;

import jxl.Workbook;
import jxl.format.Alignment;
import jxl.format.Border;
import jxl.format.BorderLineStyle;
import jxl.format.VerticalAlignment;
import jxl.write.Label;
import jxl.write.NumberFormats;
import jxl.write.WritableCellFormat;
import jxl.write.WritableSheet;
import jxl.write.WritableWorkbook;
import net.abbp.core.util.StringUtils;
import net.abbp.dao.DaoFactory;
import net.abbp.dao.IDao;
import net.abbp.dao.condition.Cnds;
import net.abbp.dao.condition.Operator;
import net.abbp.mtr.config.ChannelManager;
import net.abbp.mtr.control.DateSelect;
import net.abbp.mtr.data.Record;

/**
 * 数据网格
 * 
 * @version 1.0 2010-12-18
 * @author lexloo(lexloo@gmail.com)
 * @since MTR 1.0
 */
public class QueryDataGrid extends JPanel {
    private JTable dataGrid;
    private DataModel dataModel;
    private IDao dao = DaoFactory.INSTANCE.newDao();
    private DatePane datePanel;

    public QueryDataGrid() {
        this.initComponents();
    }

    /**
     * 初始化
     */
    private void initComponents() {
        this.setLayout(new BorderLayout());
        this.dataModel = new DataModel();
        this.dataGrid = new JTable(this.dataModel);
        this.dataGrid.getTableHeader().setPreferredSize(new Dimension(10000, 24));
        this.dataGrid.setRowHeight(24);

        this.add(new JScrollPane(dataGrid));
        datePanel = new DatePane();
        this.add(datePanel, BorderLayout.NORTH);
    }

    /**
	 * 
	 */
    private void initChannelData() {
        this.dataModel.clear();
        Date v = this.datePanel.getSelectDate();
        Calendar c = Calendar.getInstance();
        c.setTime(v);
        c.set(Calendar.AM_PM, Calendar.AM);
        c.set(Calendar.HOUR, 0);
        c.set(Calendar.MINUTE, 0);
        c.set(Calendar.SECOND, 0);
        c.set(Calendar.MILLISECOND, 0);

        Date start = c.getTime();
        c.add(Calendar.DATE, 1);

        Date end = c.getTime();

        List<Record> recordList = dao.query(Record.class, Cnds.and("time", Operator.GreaterThanOrEqual, start).and(
                "time", Operator.LessThan, end));

        for (Record r : recordList) {
            this.dataModel.addData(r.getChannel(), r);
        }

        this.dataModel.fireTableDataChanged();
    }

    private class DataModel extends DefaultTableModel {
        ChannelManager cm = ChannelManager.INSTANCE;

        public DataModel() {
            super(new String[] { "通道", "描述", "时间", "温度" }, 0);
        }

        public void clear() {
            this.dataVector.clear();
        }

        /**
         * 刷新
         * 
         * @param channel
         *            通道
         * @param data
         *            数据
         */
        @SuppressWarnings("unchecked")
        public void refresh(String channel, List<Record> data) {
            dataVector.clear();

            for (Record pd : data) {
                Vector row = new Vector();

                row.add(channel);
                row.add(cm.getChannelConfig(channel));
                row.add(pd.getTime());
                row.add(pd.getValue());

                dataVector.add(row);
            }

            this.fireTableDataChanged();
        }

        /**
         * 添加点
         * 
         * @param channel
         *            通道
         * @param pointData
         *            点数据
         */
        @SuppressWarnings("unchecked")
        public void addData(String channel, Record pointData) {
            Vector row = new Vector();

            row.add(channel);
            row.add(cm.getChannelConfig(channel));
            row.add(pointData.getTime());
            row.add(pointData.getValue());

            dataVector.add(0, row);

            this.fireTableDataChanged();
        }

        @Override
        public boolean isCellEditable(int rowIndex, int columnIndex) {
            return false;
        }

        @Override
        public Class<?> getColumnClass(int columnIndex) {
            return columnType[columnIndex];
        }

        private Class<?>[] columnType = new Class[] { String.class, String.class, String.class, String.class };
    }

    private class DatePane extends JPanel {

        private DateSelect ds;

        private DatePane() {
            this.initComponents();
        }

        /**
         * 初始化
         */
        private void initComponents() {
            this.setLayout(new FlowLayout(FlowLayout.LEFT));

            this.setBorder(BorderFactory.createCompoundBorder(BorderFactory.createEmptyBorder(4, 4, 4, 4),
                    BorderFactory.createTitledBorder("查询")));

            this.add(new JLabel("日期"));
            this.add(ds = new DateSelect());

            JButton btnQuery = new JButton("查询");
            btnQuery.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    initChannelData();
                }
            });
            this.add(btnQuery);

            final JButton btnExport = new JButton("导出");
            btnExport.addActionListener(new ActionListener() {

                @Override
                public void actionPerformed(ActionEvent e) {
                    JFileChooser fc = new JFileChooser();
                    fc.setFileFilter(new FileNameExtensionFilter("Excel文件", "xls"));
                    fc.setDialogTitle("导出为Excel文件");

                    Window wnd = SwingUtilities.getWindowAncestor(btnExport);
                    if (fc.showSaveDialog(wnd) == JFileChooser.APPROVE_OPTION) {
                        String fileName = getValidFileName(fc.getSelectedFile().getAbsolutePath(), ".xls");
                        exportXls(dataModel, fileName);

                        JOptionPane.showMessageDialog(wnd, "成功导出Excel文件!");
                    }
                }

                private void exportXls(DataModel dataModel, String fileName) {
                    try {
                        WritableCellFormat formatHead = new WritableCellFormat(NumberFormats.TEXT);
                        formatHead.setBorder(Border.ALL, BorderLineStyle.THIN);
                        formatHead.setVerticalAlignment(VerticalAlignment.CENTRE);
                        formatHead.setAlignment(Alignment.CENTRE);
                        formatHead.setWrap(true);

                        WritableCellFormat formatCenter = new WritableCellFormat(NumberFormats.TEXT);
                        formatCenter.setBorder(Border.ALL, BorderLineStyle.THIN);
                        formatCenter.setVerticalAlignment(VerticalAlignment.CENTRE);
                        formatCenter.setAlignment(Alignment.CENTRE);
                        formatCenter.setWrap(true);

                        WritableCellFormat formatRight = new WritableCellFormat(NumberFormats.TEXT);
                        formatRight.setBorder(Border.ALL, BorderLineStyle.THIN);
                        formatRight.setVerticalAlignment(VerticalAlignment.CENTRE);
                        formatRight.setAlignment(Alignment.RIGHT);
                        formatRight.setWrap(true);
                        // 创建工作薄
                        WritableWorkbook workbook = Workbook.createWorkbook(new File(fileName));
                        // 创建工作表
                        WritableSheet sheet = workbook.createSheet("温度监控结果", 0);
                        sheet.setColumnView(0, 10);
                        sheet.setColumnView(1, 30);
                        sheet.setColumnView(2, 30);
                        sheet.setColumnView(3, 10);
                        sheet.addCell(new Label(0, 0, "通道", formatHead));
                        sheet.addCell(new Label(1, 0, "描述", formatHead));
                        sheet.addCell(new Label(2, 0, "时间", formatHead));
                        sheet.addCell(new Label(3, 0, "温度", formatHead));
                        sheet.setRowView(0, 400);

                        for (int i = 0, size = dataModel.getRowCount(); i < size; i++) {
                            sheet.setRowView(i + 1, 400);
                            sheet.addCell(new Label(0, i + 1, StringUtils.convertToString(dataModel.getValueAt(i, 0),
                                    ""), formatCenter));
                            sheet.addCell(new Label(1, i + 1, StringUtils.convertToString(dataModel.getValueAt(i, 1),
                                    ""), formatCenter));
                            sheet.addCell(new Label(2, i + 1, StringUtils.convertToString(dataModel.getValueAt(i, 2),
                                    ""), formatCenter));
                            sheet.addCell(new Label(3, i + 1, StringUtils.convertToString(dataModel.getValueAt(i, 3),
                                    ""), formatRight));
                        }

                        workbook.write();
                        workbook.close();
                    } catch (Exception ex) {
                        ex.printStackTrace();
                    }
                }
            });
            this.add(btnExport);
        }

        private Date getSelectDate() {
            return (Date) ds.getValue();
        }

        private String getValidFileName(String absolutePath, String ext) {
            String fileName = absolutePath;

            if (!fileName.toLowerCase().endsWith(ext)) {
                fileName = fileName + ext;
            }

            return fileName;
        }
    }
}
